package com.atguigu.srb.core.service.impl;

import com.alibaba.excel.EasyExcel;
import com.atguigu.srb.core.listener.ExcelDictDTOListener;
import com.atguigu.srb.core.mapper.DictMapper;
import com.atguigu.srb.core.pojo.dto.ExcelDictDTO;
import com.atguigu.srb.core.pojo.entity.Dict;
import com.atguigu.srb.core.service.DictService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 数据字典 服务实现类
 * </p>
 *
 * @author lupengning
 * @since 2021-05-27
 */
@Slf4j
@Service
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService {

  @Autowired
  private RedisTemplate redisTemplate;

  @Transactional(rollbackFor = Exception.class)
  @Override
  public void importData(InputStream inputStream) {
    EasyExcel.read(inputStream, ExcelDictDTO.class,new ExcelDictDTOListener(baseMapper)).sheet().doRead();
    log.info("导入Excel成功！");
  }

  /**
   * 将数据库中数据字典的数据获取后转化成excel需要的数据格式转化后返回
   * @return
   */
  @Override
  public List<ExcelDictDTO> listDictData() {
    List<Dict> dictLists = baseMapper.selectList(null);
    List<ExcelDictDTO> excelDictDTOS = new ArrayList<ExcelDictDTO>(dictLists.size());
    dictLists.forEach(dictList -> {
      ExcelDictDTO excelDictDTO = new ExcelDictDTO();
      BeanUtils.copyProperties(dictList,excelDictDTO);
      excelDictDTOS.add(excelDictDTO);
    });
    return excelDictDTOS;
  }

  /**
   * 根据parentId获取数据字典
   * @param parentId
   * @return
   */
  @Override
  public List<Dict> listByParentId(Long parentId) {
    //从redis查看是否有缓存，有则直接返回
    try {
      log.info("从redis中获取数据字典");
      List<Dict> dictList = (List<Dict>) redisTemplate.opsForValue().get("srb:core:dictList:" + parentId);
      if (dictList != null) {
        return dictList;
      }
    } catch (Exception e) {
      log.error("redis服务器异常" + ExceptionUtils.getStackTrace(e));
    }

    log.info("从数据库中获取数据字典");
    QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();
    dictQueryWrapper.eq("parent_id", parentId);
    List<Dict> dictLists = baseMapper.selectList(dictQueryWrapper);
    dictLists.forEach(dict -> {
      boolean hasChildren = this.hasChildren(dict.getId());
      dict.setHasChildren(hasChildren);
    });

    try {
      log.info("从redis中存入数据字典");
      redisTemplate.opsForValue().set("srb:core:dictList:" + parentId,dictLists,5, TimeUnit.MINUTES);
    } catch (Exception e) {
      log.error("redis服务器异常" + ExceptionUtils.getStackTrace(e));
    }

    return dictLists;
  }

  @Override
  public List<Dict> findByDictCode(String dictCode) {

    QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();
    dictQueryWrapper.eq("dict_code", dictCode);
    Dict dict = baseMapper.selectOne(dictQueryWrapper);
    return this.listByParentId(dict.getId());
  }

  @Override
  public String getNameByParentDictCodeAndValue(String dictCode, Integer value) {

    LambdaQueryWrapper<Dict> queryWrapper = new LambdaQueryWrapper<>();
    Dict parentDict = baseMapper.selectOne(queryWrapper.eq(Dict::getDictCode, dictCode));

    if (parentDict == null) {
      return "";
    }

    queryWrapper = new LambdaQueryWrapper<>();
    Dict dict = baseMapper.selectOne(
        queryWrapper.eq(Dict::getParentId, parentDict.getId()).eq(Dict::getValue, value));

    if (dict == null) {
      return "";
    }
    return dict.getName();

  }

  /**
   * 判断当前节点下有没有子节点
   * @param id
   * @return
   */
  private boolean hasChildren(Long id) {
    QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();
    dictQueryWrapper.eq("parent_id", id);
    Integer count = baseMapper.selectCount(dictQueryWrapper);
    if (count.intValue() > 0) {
      return true;
    }
    return false;
  }
}
